package com.atguigu.gmall.list.receiver;

import com.atguigu.gmall.common.constant.RabbitConst;
import com.atguigu.gmall.list.service.api.SearchService;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author: 封捷
 * @create-date: 2022/9/9 14:52
 */
@Slf4j
@Component
@Configuration
public class GoodsReceiver {

    @Autowired
    private SearchService searchService;

    @SneakyThrows
    @RabbitListener(
            // bindings 属性：配置交换机和队列直接的路由关系
            bindings = @QueueBinding(

                    // @Queue 注解的 durable 属性设置为 true，表示队列要持久化
                    // @Queue 注解的 autoDelete 属性设置为 false，表示队列关闭自动删除
                    value = @Queue(value = RabbitConst.RABBIT_QUEUE_GOODS_IMPORT,
                            durable = "true",
                            autoDelete = "false"),

                    // @Exchange 注解的 durable 属性设置为 true，表示队列要持久化
                    // @Exchange 注解的 autoDelete 属性设置为 false，表示队列关闭自动删除
                    exchange = @Exchange(value = RabbitConst.RABBIT_EXCHANGE_GOODS),

                    // 设置当前绑定关系中对应的路由键
                    key = {RabbitConst.RABBIT_ROUTING_KEY_GOODS_IMPORT}
            )
    )
    public void goodsImport(
            // 通过消息队列发送过来的参数
            Long skuId,

            // 消息
            Message message,

            // 当前所属的频道，可以用来返回手动确认消息
            Channel channel) {

        try {
            // 执行核心操作：商品数据装入
            searchService.importGoodsToElasticSearch(skuId);

            // 手动返回 ACK 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();

            Boolean redelivered = message.getMessageProperties().getRedelivered();

            if (redelivered) {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }
    }

    @SneakyThrows
    @RabbitListener(
            // bindings 属性：配置交换机和队列直接的路由关系
            bindings = @QueueBinding(

                    // @Queue 注解的 durable 属性设置为 true，表示队列要持久化
                    // @Queue 注解的 autoDelete 属性设置为 false，表示队列关闭自动删除
                    value = @Queue(value = RabbitConst.RABBIT_QUEUE_GOODS_REMOVE,
                            durable = "true",
                            autoDelete = "false"),

                    // @Exchange 注解的 durable 属性设置为 true，表示队列要持久化
                    // @Exchange 注解的 autoDelete 属性设置为 false，表示队列关闭自动删除
                    exchange = @Exchange(value = RabbitConst.RABBIT_EXCHANGE_GOODS),

                    // 设置当前绑定关系中对应的路由键
                    key = {RabbitConst.RABBIT_ROUTING_KEY_GOODS_REMOVE}
            )
    )
    public void goodsRemove(Long skuId, Message message, Channel channel) {
        try {
            searchService.removeGoodsFromElasticSearch(skuId);

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();

            Boolean redelivered = message.getMessageProperties().getRedelivered();

            if (redelivered) {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }
    }

}
